
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>MySQL like的模糊查询如何优化 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>MySQL like的模糊查询如何优化 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">为什么使用 `LIKE '%...%'` 进行模糊查询会导致 MySQL 性能低下？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">因为它会导致全表扫描。MySQL需要遍历表中的所有记录，对每一行的目标字段进行字符串匹配，并且即使找到了足够数量的结果（如LIMIT 100），它仍然会扫描完整个表，效率极低。</div>
          </div>
          <div class="card-source">来源: 一、为什么LIKE查询是性能杀手</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">文档中提到了哪四种常见的、会导致性能问题的 `LIKE` 查询错误写法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. 双百分号暴击（`LIKE '%...%'`）；2. 索引失效陷阱（以'%'开头的模糊查询）；3. 大字段轰炸（对TEXT等大字段进行模糊查询）；4. 无节制分页（深分页与模糊查询结合）。</div>
          </div>
          <div class="card-source">来源: 二、四大常见错误写法（你至少中过两招）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在业务层面上，可以通过哪些方法来优化基于 `LIKE` 的搜索功能？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">可以采用两种策略：1. **搜索条件限制**：例如要求最小搜索长度、禁用特殊符号、建立关键词白名单。2. **缓存预热策略**：为热点关键词创建缓存，预先计算并存储搜索结果，避免重复的慢查询。</div>
          </div>
          <div class="card-source">来源: 三、业务层优化</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">如何利用前缀索引优化 `LIKE` 查询？这种方法有什么限制？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过在字段的前N个字符上创建索引（例如 `ADD INDEX idx_title_prefix (title(10))`），可以优化查询。但这种方法的限制是它只对左匹配的查询有效，例如 `WHERE title LIKE '夏季新款%'`，而对 `LIKE '%新款'` 无效。</div>
          </div>
          <div class="card-source">来源: 四、数据库层优化 > 1. 前缀索引优化</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">文档中介绍的“倒排索引方案”是如何在MySQL中实现的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过创建一个关键词映射表（`product_keywords`），将每个产品ID与其包含的关键词关联起来。查询时，不再对原表进行模糊匹配，而是通过JOIN这个映射表，并对关键词进行精确匹配（例如 `WHERE k.keyword = '新款'`）来找到对应的产品。</div>
          </div>
          <div class="card-source">来源: 四、数据库层优化 > 2. 倒排索引方案</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">方案</div>
          <div class="card-question">当数据量超过千万级时，文档推荐的终极解决方案是什么？它相比MySQL有哪些优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">方案</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">终极解决方案是使用专业的搜索引擎，如 Elasticsearch 或 MeiliSearch。相比MySQL，它们的优势在于响应时间极快（通常在10-50ms），并且支持分词、同义词、拼音搜索等更强大的功能。</div>
          </div>
          <div class="card-source">来源: 五、终极解决方案</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">什么是“虚拟列”技术（MySQL 5.7+），它如何帮助优化 `LIKE` 查询？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">虚拟列是一种其值由其他列计算而来的列。可以创建一个虚拟列来存储目标字段的前缀（如 `GENERATED ALWAYS AS (LEFT(title, 20))`），然后在这个虚拟列上建立索引。这样，对前缀的模糊查询（如 `WHERE title_prefix LIKE '夏季%'`）就可以利用到索引，从而提升性能。</div>
          </div>
          <div class="card-source">来源: 四、数据库层优化 > 3. 虚拟列魔法（MySQL 5.7+）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">文档提到的“隐式类型转换”陷阱是指什么？为什么它会影响查询性能？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">“隐式类型转换”陷阱指的是在 `LIKE` 查询中使用了非字符串类型的值，例如在一个VARCHAR类型的字段上使用 `LIKE CONCAT('%', 123, '%')`。MySQL可能会因为需要转换类型而无法使用已有的索引，导致查询性能下降。</div>
          </div>
          <div class="card-source">来源: 六、这些细节让你前功尽弃 > 2. 隐式类型转换</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">文档最后总结了处理 `LIKE` 查询的三个核心原则是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. **能不用LIKE就不用**：优先选择等值查询。2. **必须用时控制查询范围**：通过增加时间范围、分类等条件进行过滤。3. **超过百万数据立即考虑搜索引擎**：当数据量较大时，应切换到专业的搜索引擎解决方案。</div>
          </div>
          <div class="card-source">来源: 最后说句得罪人的话</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
